package org.crl.blogsystem.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.crl.blogsystem.entity.Blog;
import org.crl.blogsystem.entity.UserFollow;
import org.crl.blogsystem.entity.dto.UpdatePasswordDTO;
import org.crl.blogsystem.entity.dto.UserBlogInfoDTO;
import org.crl.blogsystem.entity.dto.UserFollowDTO;
import org.crl.blogsystem.message.ResponseMessage;
import org.crl.blogsystem.entity.User;
import org.crl.blogsystem.entity.dto.UserDTO;
import org.crl.blogsystem.repository.UserFollowRepository;
import org.crl.blogsystem.repository.UserRepository;
import org.crl.blogsystem.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE, RequestMethod.PUT})
public class UserController {

    public UserDTO convertToDTO(User user) {
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setPhone(user.getPhone());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setPassword(user.getPassword());
        userDTO.setUsername(user.getUsername());
        userDTO.setSignature(user.getSignature());
        userDTO.setBirth_day(user.getBirthday());
        userDTO.setSex(user.getSex());
        return userDTO;
    }

    public UserDTO convertToUserInfoDTO(User user) {
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        UserFollow userFollow = userFollowRepository.findByFollowerIdAndFollowingId(StpUtil.getLoginIdAsLong(), user.getId());
        if (userFollow != null && userFollow.getState() == 1) {
            userDTO.setIsFollowing(true);
        } else {
            userDTO.setIsFollowing(false);
        }
        userDTO.setAvatar(user.getAvatar());
        userDTO.setUsername(user.getUsername());
        userDTO.setSignature(user.getSignature());
        userDTO.setBirth_day(user.getBirthday());
        userDTO.setSex(user.getSex());
        userDTO.setFollowCount(user.getFollowcount());
        userDTO.setFollowerCount(user.getFollowercount());
        return userDTO;
    }

    public UserBlogInfoDTO convertToUserBlogInfoDTO(User user) {
        UserBlogInfoDTO userBlogInfoDTO =  new UserBlogInfoDTO();
        userBlogInfoDTO.setId(user.getId());
        userBlogInfoDTO.setUsername(user.getUsername());
        userBlogInfoDTO.setAvatar(user.getAvatar());
        return userBlogInfoDTO;
    }

    public UserDTO convertToUserSimpleInfoDTO(User user) {
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setSignature(user.getSignature());
        return userDTO;
    }

    public List<UserDTO> convertToDTOList(List<User> users) {
        return users.stream().map(this::convertToDTO).toList();
    }

    public UserFollowDTO convertToUserSimpleDTO(UserFollow userFollow) {
        UserFollowDTO userFollowDTO = new UserFollowDTO();
        userFollowDTO.setId(userFollow.getId());
        userFollowDTO.setFollowerId(userFollow.getFollower().getId());
        userFollowDTO.setFollowingId(userFollow.getFollowing().getId());
        userFollowDTO.setState(userFollow.getState());
        return userFollowDTO;
    }

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    IUserService userService;

    @Autowired
    UserRepository userRepository;

    @Autowired
    IBlogService blogService;

    @Autowired
    UserFollowRepository userFollowRepository;


    /**
     * 注册
     * @param userDTO 用户信息
     * @return 注册结果
     */
    @PostMapping("/register")
    public ResponseMessage<User> add(@RequestBody UserDTO userDTO) {
        User newUser = userService.add(userDTO);
        if (newUser != null) {
            return ResponseMessage.success(newUser);
        }else {
            return ResponseMessage.exist();
        }
    }

    /**
     * 删除用户
     * @param id 用户id
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    public ResponseMessage<String> delete(@PathVariable("id") Long id) {
        StpUtil.checkLogin();
        userService.delete(id);
        return ResponseMessage.success("删除成功");
    }

    /**
     * 修改用户信息
     * @param userDTO 用户信息
     * @return 修改结果
     */
    @PutMapping("/setting/info")
    public ResponseMessage<UserDTO> update(@RequestBody UserDTO userDTO) {
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        User updatedUser = userService.update(userId, userDTO);
        UserDTO dto = convertToDTO(updatedUser);
        return ResponseMessage.success(dto);
    }

    /**
     * 修改密码
     * @param updatePasswordDTO 修改密码信息
     * @return 修改结果
     */
    @PutMapping("/setting/password")
    public ResponseMessage<String> updatePassword(@RequestBody UpdatePasswordDTO updatePasswordDTO) {
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        String oldPassword = updatePasswordDTO.getOldPassword();
        String newPassword = updatePasswordDTO.getNewPassword();
        if (userService.changePassword(userId, oldPassword, newPassword)) {
            return ResponseMessage.success("修改成功");
        }else {
            return ResponseMessage.fail("原密码错误");
        }

    }

    /**
     * 上传头像
     * @param avatarImage 头像图片
     * @return 上传结果
     */
    @PutMapping("/setting/avatar")
    public ResponseMessage<String> uploadAvatar(@RequestParam("file") MultipartFile avatarImage) {
        StpUtil.checkLogin();
        String res = userService.uploadAvatar(avatarImage);
        return res.equals("上传失败") ? ResponseMessage.fail("上传失败") : ResponseMessage.success(res);
    }

    /**
     * 搜索用户
     * @param key 关键词
     * @return 用户列表
     */
    @GetMapping("/search")
    public ResponseMessage<List<UserDTO>> search(@RequestParam("key") String key) {
        StpUtil.checkLogin();
        List<User> userList = userRepository.findAllByUsernameContaining(key);
        List<UserDTO> userDTOList = new ArrayList<>();
        for (User user : userList) {
            UserDTO userDTO = convertToUserSimpleInfoDTO(user);
            userDTOList.add(userDTO);
        }
        return ResponseMessage.success(userDTOList);
    }

    /**
     * 根据博客id获取用户信息
     * @param blogId 博客id
     * @return 用户信息
     */
    @GetMapping("/blog/{blog_id}")
    public ResponseMessage<UserBlogInfoDTO> getByBlogId(@PathVariable("blog_id") Long blogId) {
        StpUtil.checkLogin();

        Blog blog = blogService.getById(blogId);
        User user = blog.getUser();
        UserBlogInfoDTO userDTO = convertToUserBlogInfoDTO(user);
        return ResponseMessage.success(userDTO);
    }


    /**
     * 登录
     * @param loginParams 手机号和密码
     * @return 登录结果
     */
    @RequestMapping("login")
    public SaResult doLogin(@RequestBody Map<String, String> loginParams) {
        String phone = loginParams.get("phone");
        String password = loginParams.get("password");
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select id from user where phone=? and password=?",phone,password);
        if (maps.size() == 0) {
            return SaResult.error("手机号或密码错误");
        }else {
            StpUtil.login(maps.get(0).get("id"));
            return SaResult.ok().setData(StpUtil.getTokenInfo());
        }
    }

    /**
     * 获取当前用户登录信息
     * @return 当前用户登录信息
     */
    @RequestMapping("tokenInfo")
    public SaResult currentUser() {
        StpUtil.checkLogin();
        return SaResult.data(StpUtil.getTokenInfo());
    }

    /**
     * 判断当前用户是否登录
     * @return 是否登录
     */
    @RequestMapping("isLogin")
    public boolean isLogin() {
        StpUtil.checkLogin();

        try{
            Long loginId = StpUtil.getLoginIdAsLong();
            return userService.isLogin(loginId) ;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取当前用户信息
     * @return 当前用户信息
     */
    @GetMapping("/getCurrentUserInfo")
    public ResponseMessage<UserDTO> getCurrentUserInfo() {
        StpUtil.checkLogin();
        User currentUserInfo = userService.getById(StpUtil.getLoginIdAsLong());
        UserDTO userDTO = convertToUserInfoDTO(currentUserInfo);
        return ResponseMessage.success(userDTO);
    }

    /**
     * 获取用户信息
     * @param userId 用户id
     * @return 用户信息
     */
    @GetMapping("/getUserInfo/{userId}")
    public ResponseMessage<UserDTO> getUserInfo(@PathVariable("userId") Long userId) {
        StpUtil.checkLogin();
        User user = userService.getById(userId);
        UserDTO userDTO = convertToUserInfoDTO(user);
        return ResponseMessage.success(userDTO);
    }

    /**
     * 退出登录
     * @return 退出结果
     */
    @RequestMapping("logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok();
    }

    /**
     * 关注/取关用户
     * @param userId 用户id
     * @return 关注/取关结果
     */
    @PostMapping("/follow/{userId}")
    public ResponseMessage<UserFollowDTO> doFollow(@PathVariable Long userId) {
        StpUtil.checkLogin();
        int res = userService.doFollow(userId);
        if(res == 1) {
            UserFollow userFollow = userFollowRepository.findByFollowerIdAndFollowingId(StpUtil.getLoginIdAsLong(), userId);
            UserFollowDTO userFollowDTO = convertToUserSimpleDTO(userFollow);
            return ResponseMessage.success(userFollowDTO);
        } else if(res == -1) {
            UserFollow userFollow = userFollowRepository.findByFollowerIdAndFollowingId(StpUtil.getLoginIdAsLong(), userId);
            UserFollowDTO userFollowDTO = convertToUserSimpleDTO(userFollow);
            return ResponseMessage.success(userFollowDTO);
        } else {
            return ResponseMessage.fail("关注失败" + res);
        }
    }

    /**
     * 获取当前用户的关注者
     * @return 关注者列表
     */
    @GetMapping("/followList")
    public ResponseMessage<Set<UserDTO>> getFollowing() {
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        Set<User> following = userService.getFollowing(userId);
        return ResponseMessage.success(
                following.stream()
                        .map(this::convertToUserSimpleInfoDTO)
                        .collect(Collectors.toSet())
        );
    }

    /**
     * 获取当前用户的粉丝
     * @return 粉丝列表
     */
    @GetMapping("/fanList")
    public ResponseMessage<Set<UserDTO>> getFans() {
        StpUtil.checkLogin();
        Long userId = StpUtil.getLoginIdAsLong();
        Set<User> fans = userService.getFollowers(userId);
        return ResponseMessage.success(
                fans.stream()
                        .map(this::convertToUserSimpleInfoDTO)
                        .collect(Collectors.toSet())
        );
    }
}
